package com.dep.util;

import lombok.extern.slf4j.Slf4j;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 日期处理工具
 */
@Slf4j
public class DateUtil {
    /**
     *
     */
    public static String datePattern = "yyyy-MM-dd";
    private static final ThreadLocal<SimpleDateFormat> threadLocalformat = new ThreadLocal<SimpleDateFormat>();

    public static String monthPattern = "yyyy-MM";
    private static final ThreadLocal<SimpleDateFormat> threadLocal = new ThreadLocal<SimpleDateFormat>();
    /**
     *
     */
    public static String timePattern = "HH:mm";

    /**
     * 在页面中显示的日期格式yyyy-MM-dd
     *
     * @return 日期显示格式
     * @Title getDatePattern
     */
    public static String getDatePattern() {
        return datePattern;
    }

    /**
     * 根据日期格式，返回日期按datePattern格式转换后的字符串
     *
     * @param aDate 日期
     * @return 日期字符串
     * @Title getDate
     */
    public static final String getDate(Date aDate) {
        SimpleDateFormat df = null;
        String returnValue = "";
        if (aDate != null) {
            df = new SimpleDateFormat(datePattern);
            returnValue = df.format(aDate);
        }
        return (returnValue);
    }

    /**
     * 指定日期格式生成当前日期字符串
     *
     * @param pattern :"yy-MM-dd"
     * @return 日期字符串
     * @Title getDate
     */
    public static final String getDate(String pattern) {
        Date date = new Date();
        return getDate(date, pattern);
    }

    /**
     * 指定日期格式生成指定日期的字符串
     *
     * @param date    时间
     * @param pattern 格式化参数
     * @return 日期字符串
     * @Title getDate
     */
    public static final String getDate(Date date, String pattern) {
        if (date != null) {
            return new SimpleDateFormat(pattern).format(date);
        }
        return "";
    }

    /**
     * 根据日期字符串和指定日期格式返回日期
     *
     * @param dateString 时间字符串
     * @param pattern    时间格式
     * @return 日期
     * @Title getDate
     */
    public static Date getDate(String dateString, String pattern) {
        SimpleDateFormat df = null;
        Date date = null;
        if (dateString != null) {
            try {
                df = new SimpleDateFormat(pattern);
                if (!dateString.equals("")) {
                    date = df.parse(dateString);
                }
            } catch (ParseException pe) {
                log.error(pe.getMessage());
            }
        }
        return date;
    }

    /**
     * 按照日期格式，将字符串解析为日期对象
     *
     * @param aMask   时间格式
     * @param strDate 日期字符
     * @return 日期
     * @Title convertStringToDate
     */
    public static final Date convertStringToDate(String aMask, String strDate) {
        SimpleDateFormat df = null;
        Date date = null;
        df = new SimpleDateFormat(aMask);
        try {
            date = df.parse(strDate);
        } catch (ParseException pe) {
            log.error(pe.getMessage());
        }
        return date;
    }

    /**
     * 获取时间字符串
     *
     * @param theTime data
     * @return 时间字符串
     * @Title getTime
     */
    public static String getTime(Date theTime) {
        return getDateTime(timePattern, theTime);
    }


    /**
     * 返回指定格式的日期字符串
     *
     * @param aMask 格式
     * @param aDate 时间
     * @return 日期字符串
     * @Title getDateTime
     */
    public static final String getDateTime(String aMask, Date aDate) {
        SimpleDateFormat df = null;
        String returnValue = "";
        if (aDate == null) {
            log.error("aDate is null!");
        } else {
            df = new SimpleDateFormat(aMask);
            returnValue = df.format(aDate);
        }
        return (returnValue);
    }

    /**
     * 根据日期格式，返回日期按datePattern格式转换后的字符串
     *
     * @param aDate date
     * @return 日期字符串
     * @Title convertDateToString
     */
    public static final String convertDateToString(Date aDate) {
        return getDateTime(datePattern, aDate);
    }


    /**
     * @return String
     * @Title: getYear
     * @author lzy
     */
    public static String getYear() {
        Date date = new Date();
        return getDate(date, "yyyy");
    }

    /**
     * @return String
     * @Title: getMonth
     * @author lzy
     */
    public static String getMonth() {
        Date date = new Date();
        return getDate(date, "MM");
    }

    /**
     * @return String
     * @Title: getDay
     * @author lzy
     */
    public static String getDay() {
        Date date = new Date();
        return getDate(date, "dd");
    }

    /**
     * 返回小时
     *
     * @param date date
     * @return 小时
     * @Title getHour
     */
    public static int getHour(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * 返回分钟
     *
     * @param date date
     * @return 分钟
     * @Title getMinute
     */
    public static int getMinute(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.MINUTE);
    }

    /**
     * 返回秒钟
     *
     * @param date date
     * @return 秒钟
     * @Title getSecond
     */
    public static int getSecond(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.SECOND);
    }

    /**
     * 返回毫秒
     *
     * @param date date
     * @return 毫秒
     * @Title getMillis
     */
    public static long getMillis(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.getTimeInMillis();
    }

    /**
     * 计算指定日期几天后的日期
     *
     * @param date date
     * @param day  天
     * @return 计算指定日期几天后的日期
     * @Title addDate
     */
    public static Date addDate(Date date, int day) {
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(getMillis(date) + ((long) day) * 24 * 3600 * 1000);
        return c.getTime();
    }

    /**
     * 计算指定日期几分钟的日期
     *
     * @param minute 分钟
     * @return 计算指定日期几分钟后的日期
     * @Title addDateMinute
     */
    public static Date addDateMinute(Date date, int minute) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MINUTE, minute);
        return c.getTime();
    }

    /**
     * 日期相减(生成日)
     *
     * @param date  时间
     * @param date1 时间
     * @return 日期相减
     * @Title diffDate
     */
    public static int diffDate(Date date, Date date1) {
        return (int) ((getMillis(date) - getMillis(date1)) / (24 * 3600 * 1000));
    }

    /**
     * 日期相减(生成小时)
     *
     * @param date  时间
     * @param date1 时间
     * @return 日期相减(生成小时)
     * @Title diffDateToHour
     */
    public static int diffDateToHour(Date date, Date date1) {
        return (int) ((getMillis(date) - getMillis(date1)) / (1000 * 60 * 60));
    }

    /**
     * 日期相减(生成分钟)
     *
     * @param date  时间
     * @param date1 时间
     * @return 日期相减(生成分钟)
     * @Title diffDateToMillis
     */
    public static int diffDateToMillis(Date date, Date date1) {
        return (int) ((getMillis(date) - getMillis(date1)) / (1000 * 60));
    }

    /**
     * 转换时间字符串
     *
     * @param dateStr 时间字符串
     * @return 转换时间字符串
     * @Title parseDateStr
     */
    public static Date parseDateStr(String dateStr) {
        try {
            dateStr = dateStr.trim();
            if (dateStr.matches("\\d{4}")) {// 2008
                dateStr += "-01-01 00:00:00";
            } else if (dateStr.matches("\\d{4}-\\d{1,2}")) {// 2008-09
                dateStr += "-01 00:00:00";
            } else if (dateStr.matches("\\d{4}-\\d{1,2}-\\d{1,2}")) {// 2008-09-12
                dateStr += " 00:00:00";
            } else if (dateStr.matches("\\d{4}-\\d{1,2}-\\d{1,2} d{1,2}:d{1,2}")) {// 2008-09-12
                // 10:20
                dateStr += ":00";
            } else if (dateStr.matches("\\d{4}-\\d{1,2}-\\d{1,2} d{1,2}:d{1,2}:d{1,2}")) {// 2008-09-12
                // 10:20:20
                //
            }
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateStr);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return null;
    }


    /**
     * 根据月数，返回多少月后的日期
     *
     * @param date   当前时间
     * @param months 月数
     * @return 处理后的时间
     */
    public static Date addMonth(Date date, int months) {
        try {

            Calendar cd = Calendar.getInstance();
            cd.setTime(date);
            cd.add(Calendar.MONTH, months);//增加一个月
            return cd.getTime();

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 得到指定月的天数
     */
    public static int getMonthLastDay(int year, int month) {
        Calendar a = Calendar.getInstance();
        a.set(Calendar.YEAR, year);
        a.set(Calendar.MONTH, month - 1);
        a.set(Calendar.DATE, 1);//把日期设置为当月第一天
        a.roll(Calendar.DATE, -1);//日期回滚一天，也就是最后一天
        int maxDate = a.get(Calendar.DATE);
        return maxDate;
    }


    /**
     * 判断选择的日期是否是本周
     *
     * @param time
     * @return
     */
    public static boolean isThisWeek(long time) {
        Calendar calendar = Calendar.getInstance();
        int currentWeek = calendar.get(Calendar.WEEK_OF_YEAR);
        calendar.setTime(new Date(time));
        int paramWeek = calendar.get(Calendar.WEEK_OF_YEAR);
        return paramWeek == currentWeek;
    }


    /**
     * 判断选择的日期是否是过去时间
     *
     * @param time
     * @return
     */
    public static boolean isbefore(long time) {
        return time >= System.currentTimeMillis();
    }


    /**
     * 判断选择的日期是否是今天
     *
     * @param time
     * @return
     */
    public static boolean isToday(long time) {
        return isThisTime(time, "yyyy-MM-dd");
    }


    /**
     * 判断选择的日期是否是本月
     *
     * @param time
     * @return
     */
    public static boolean isThisMonth(long time) {
        return isThisTime(time, "yyyy-MM");
    }

    private static boolean isThisTime(long time, String pattern) {
        Date date = new Date(time);
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        String param = sdf.format(date);//参数时间
        String now = sdf.format(new Date());//当前时间
        return param.equals(now);
    }

    /**
     * 获取日期范围内的所有日期集合
     *
     * @param start 起始日期
     * @param end   结束日期
     * @return
     */
    public static List<String> getAllDates(String start, String end) { //
        List<String> list = new ArrayList<String>(); //保存日期集合
        try {
            SimpleDateFormat format = threadLocalformat.get();
            if(format == null){
                format = new SimpleDateFormat(datePattern);
            }
            Date dateStart = format.parse(start);
            Date dateEnd = format.parse(end);
            Date date = dateStart;
            Calendar cd = Calendar.getInstance();//用Calendar 进行日期比较判断
            while (date.getTime() <= dateEnd.getTime()) {
                list.add(format.format(date));
                cd.setTime(date);
                cd.add(Calendar.DATE, 1);//增加一天 放入集合
                date = cd.getTime();
            }
        } catch (ParseException e) {
            log.error(e.getMessage(), e);
        }
        return list;
    }

    /**
     * 开始/结束日期查询月份集合
     *
     * @param start
     * @param end
     * @return
     * @throws Exception
     */
    public static List<String> getMonthBetween(String start, String end) {
        ArrayList<String> result = new ArrayList<String>();
        try {
            SimpleDateFormat formatMonth = threadLocal.get();
            if(formatMonth == null){
                formatMonth = new SimpleDateFormat(monthPattern);
            }

            Date dateStart = formatMonth.parse(start);
            Date dateEnd = formatMonth.parse(end);

            Calendar min = Calendar.getInstance();
            Calendar max = Calendar.getInstance();

            min.setTime(dateStart);
            min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);

            max.setTime(dateEnd);
            max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);

            while (min.before(max)) {
                result.add(formatMonth.format(min.getTime()));
                min.add(Calendar.MONTH, 1);
            }
        } catch (ParseException e) {
            log.error(e.getMessage(), e);
        }

        return result;
    }

    /**
     * 本月第一天日期
     *
     * @return
     */
    public static String getFirstDay() {
        //获取前月的第一天
        Calendar cal_1 = Calendar.getInstance();//获取当前日期
        //        cal_1.add(Calendar.MONTH, -1);
        cal_1.set(Calendar.DAY_OF_MONTH, 1);//设置为1号,当前日期既为本月第一天
        SimpleDateFormat format = threadLocalformat.get();
        if(format == null){
            format = new SimpleDateFormat(datePattern);
        }
        return format.format(cal_1.getTime());
    }
    /**
     * 本年第一个月第一天
     *
     * @return
     */
    public static String getFirstMonth() {
        Calendar cal = Calendar.getInstance();//获取当前日期
        cal.set(cal.get(Calendar.YEAR), Calendar.JANUARY,1);
        SimpleDateFormat format = threadLocalformat.get();
        if(format == null){
            format = new SimpleDateFormat(datePattern);
        }
        return format.format(cal.getTime());
    }


}